﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Xml;

namespace HtmlHelper
{
    public class HtmlElement2
    {
        // Fields
        private string tagName;
        private string text;
        
        protected Dictionary<string,string> attributes=new Dictionary<string,string> ();
        public Dictionary<string, string> Attributes
        {
            get
            {
                return this.attributes;
            }
        }
        
        private string attributesHTML;
        
        private HtmlElement2 parent;
        
        protected ArrayList children;
        private XhHtmlElementType type = XhHtmlElementType.Tag;

        // Properties

        public string AttributesHTML
        {
            get
            {
                return this.attributesHTML;
            }
            set
            {
                if (value == null)
                {
                    value = "";
                }
                this.attributesHTML = value.Replace('\n', ' ');
                this.attributesHTML = this.attributesHTML.Replace('\r', ' ');
                this.attributesHTML = this.attributesHTML.Replace('<', ' ');
                this.attributesHTML = this.attributesHTML.Replace('>', ' ');
                this.ParseAttributesHTML();
            }
        }

        public ArrayList ChildElements
        {
            get
            {
                if (this.children == null)
                {
                    this.children = new ArrayList();
                }
                return this.children;
            }
        }

        public string InnerHTML
        {
            get
            {
                string str = "";
                if (this.type == XhHtmlElementType.Tag)
                {
                    str = "<" + this.tagName;
                    if (this.attributes.Count > 0)
                    {
                        IDictionaryEnumerator enumerator = this.attributes.GetEnumerator();
                        while (enumerator.MoveNext())
                        {
                            DictionaryEntry current = (DictionaryEntry)enumerator.Current;
                            string str2 = str;
                            str = str2 + " " + ((string)current.Key) + "=\"" + ((string)current.Value) + "\"";
                        }
                    }
                    if ((this.children != null) && (this.children.Count > 0))
                    {
                        str = str + ">";
                        foreach (HtmlElement2 element in this.children)
                        {
                            str = str + element.InnerHTML;
                        }
                        return (str + "</" + this.tagName + ">");
                    }
                    if (this.tagName == "script")
                    {
                        return (str + "></script>");
                    }
                    return (str + " />");
                }
                if (this.type != XhHtmlElementType.Script)
                {
                }
                return this.text;
            }
        }

        public string InnerText
        {
            get
            {
                string str = "";
                if (this.type == XhHtmlElementType.Tag)
                {
                    if (this.children != null)
                    {
                        foreach (HtmlElement2 element in this.children)
                        {
                            if ((element.Type == XhHtmlElementType.Text) || (element.Type == XhHtmlElementType.Tag))
                            {
                                str = str + element.InnerText;
                            }
                        }
                    }
                    return str;
                }
                if (this.type == XhHtmlElementType.Text)
                {
                    return this.text;
                }
                if (this.type == XhHtmlElementType.Comment)
                {
                    str = this.text.Replace("<!--", "").Replace("<!-", "").Replace("-->", "").Replace("->", "").Replace("-", "");
                }
                return str;
            }
        }

        public HtmlElement2 Parent
        {
            get
            {
                return this.parent;
            }
            set
            {
                this.parent = value;
            }
        }

        public string TagName
        {
            get
            {
                return this.tagName;
            }
            set
            {
                this.tagName = value;
            }
        }

        public string Text
        {
            get
            {
                return this.text;
            }
            set
            {
                this.text = value;
            }
        }

        public XhHtmlElementType Type
        {
            get
            {
                return this.type;
            }
            set
            {
                this.type = value;
            }
        }
        
        // Methods
        public HtmlElement2()
        {
        }

        public HtmlElement2(XhHtmlElementType type)
        {
            this.type = type;
        }

        public HtmlElement2(string tagName)
        {
            this.tagName = tagName;
        }

        private void ParseAttributesHTML()
        {
            int length = 0;
            this.attributes.Clear();
            string s = this.attributesHTML;
            do
            {
                string str;
                length = s.IndexOf("=");
                int index = s.IndexOf(" ");
                if (((index >= 0) && (index < length)) && (s.Substring(0, length).Replace(" ", "") != s.Substring(0, index)))
                {
                    str = s.Substring(0, index).Replace(",", "").Replace("\"", "").Replace("'", "");
                    if (str == "")
                    {
                        s = s.Substring(index + 1).Trim();
                    }
                    else
                    {
                        s = s.Substring(index + 1).Trim();
                        try
                        {
                            this.attributes.Add(str, "");
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
                else if (length >= 0)
                {
                    string str2;
                    str = s.Substring(0, length);
                    s = s.Substring(length + 1).Trim();
                    if ((s.Length > 0) && ((s[0] == '"') || (s[0] == '\'')))
                    {
                        if (s[0] == '"')
                        {
                            length = s.IndexOf('"', 1);
                        }
                        else
                        {
                            length = s.IndexOf('\'', 1);
                        }
                        if (length >= 0)
                        {
                            str2 = s.Substring(1, length - 1);
                            s = s.Substring(length + 1).Trim();
                        }
                        else
                        {
                            str2 = s;
                            s = "";
                        }
                    }
                    else
                    {
                        length = s.IndexOf(' ');
                        if (length >= 0)
                        {
                            str2 = s.Substring(0, length);
                            s = s.Substring(length + 1).Trim();
                        }
                        else
                        {
                            str2 = s;
                            s = "";
                        }
                    }
                    try
                    {
                        this.attributes.Add(str.ToLower().Trim(), str2);
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            while (length >= 0);
        }

        internal void A(string I0, ArrayList J0)
        {
            if (this.children != null)
            {
                foreach (HtmlElement2 element in this.children)
                {
                    if (element.TagName == I0)
                    {
                        J0.Add(element);
                    }
                    element.A(I0, J0);
                }
            }
        }

        public void AppendChild(HtmlElement2 child)
        {
            child.Parent = this;
            this.ChildElements.Add(child);
        }

        internal XmlNode B(XmlElement K0)
        {
            if (this.type != XhHtmlElementType.Tag)
            {
                if (this.type == XhHtmlElementType.Text)
                {
                    XmlText text = K0.OwnerDocument.CreateTextNode(this.text);
                    K0.AppendChild(text);
                    return text;
                }
                if (this.type == XhHtmlElementType.Comment)
                {
                    XmlComment comment = K0.OwnerDocument.CreateComment(this.InnerText);
                    K0.AppendChild(comment);
                    return comment;
                }
                if (this.type == XhHtmlElementType.Script)
                {
                    XmlCDataSection section = K0.OwnerDocument.CreateCDataSection(this.text);
                    K0.AppendChild(section);
                    return section;
                }
                return null;
            }
            XmlElement newChild = null;
            try
            {
                newChild = K0.OwnerDocument.CreateElement(this.tagName);
            }
            catch (Exception)
            {
                return null;
            }
            K0.AppendChild(newChild);
            IDictionaryEnumerator enumerator = this.attributes.GetEnumerator();
            while (enumerator.MoveNext())
            {
                DictionaryEntry current = (DictionaryEntry)enumerator.Current;
                try
                {
                    newChild.SetAttribute((string)current.Key, (string)current.Value);
                    continue;
                }
                catch (Exception)
                {
                    continue;
                }
            }
            if (this.children != null)
            {
                foreach (HtmlElement2 element2 in this.children)
                {
                    element2.B(newChild);
                }
            }
            return newChild;
        }

        public HtmlElement2 FindElement(string tagname)
        {
            if (this.children != null)
            {
                foreach (HtmlElement2 element in this.children)
                {
                    if (element.TagName == tagname)
                    {
                        return element;
                    }
                    HtmlElement2 element2 = element.FindElement(tagname);
                    if (element2 != null)
                    {
                        return element2;
                    }
                }
            }
            return null;
        }

        public string GetAttribute(string AttributeName)
        {
            return (this.attributes[AttributeName] as string);
        }

        public ArrayList GetElementsByTagName(string tagname)
        {
            ArrayList list = new ArrayList(10);
            this.A(tagname, list);
            return list;
        }

        public bool HasAttribute(string attributename)
        {
            return this.attributes.ContainsKey(attributename);
        }

        public void RemoveChild(HtmlElement2 child)
        {
            this.ChildElements.Remove(child);
        }

        public void SetAttribute(string AttributeName, string AttributeValue)
        {
            this.attributes[AttributeName] = AttributeValue;
        }

        public override string ToString()
        {
            return this.InnerHTML;
        }

        public XmlDocument ToXMLDocument()
        {
            if (this.type != XhHtmlElementType.Tag)
            {
                throw new InvalidOperationException("Only elements of type Tag can be serialized to XmlDocument.");
            }
            XmlDocument document = new XmlDocument();
            XmlElement newChild = document.CreateElement(this.tagName);
            document.AppendChild(newChild);
            IDictionaryEnumerator enumerator = this.attributes.GetEnumerator();
            while (enumerator.MoveNext())
            {
                DictionaryEntry current = (DictionaryEntry)enumerator.Current;
                newChild.SetAttribute((string)current.Key, (string)current.Value);
            }
            if (this.children != null)
            {
                foreach (HtmlElement2 element2 in this.children)
                {
                    element2.B(newChild);
                }
            }
            document.PreserveWhitespace = true;
            return document;
        }

        public void WriteTo(XmlWriter writer)
        {
            if (this.type == XhHtmlElementType.Tag)
            {
                writer.WriteStartElement(this.tagName);
                IDictionaryEnumerator enumerator = this.attributes.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    DictionaryEntry current = (DictionaryEntry)enumerator.Current;
                    writer.WriteAttributeString((string)current.Key, (string)current.Value);
                }
                if (this.children != null)
                {
                    foreach (HtmlElement2 element in this.children)
                    {
                        element.WriteTo(writer);
                    }
                }
                writer.WriteEndElement();
            }
            else if (this.type == XhHtmlElementType.Text)
            {
                writer.WriteString(this.text);
            }
            else if (this.type == XhHtmlElementType.Comment)
            {
                writer.WriteComment(this.text);
            }
            else if (this.type == XhHtmlElementType.Script)
            {
                writer.WriteCData(this.text);
            }
        }

    }
}
